Repository navigation
Bound chemistry face states with a scaling limiter (NaN at finite-cylinder rims) - #1975
Draft
sbryngelson wants to merge 2 commits into
Draft
sbryngelson wants to merge 2 commits into
sbryngelson wants to merge 2 commits into
Conversation
…finite-cylinder rims) At the cap/side rim of a finite IB cylinder (and any sharp IB corner) the ghost layers seen by one fluid cell mirror different faces: the first layer mirrors the side, deeper layers mirror the cap's stagnation region. With a hot isothermal wall the ghost column is then non-monotone, WENO overshoots the fluid/ghost face to ~7600 K, past the NASA fit where cp < 0, and HLLC returns a NaN sound speed. With chemistry, a reconstructed face state whose density or temperature is not positive, or whose temperature exceeds T_surface_max, now falls back to its cell's state. Adds a 2D hot-wall IB rectangle regression test that NaNs on master by step 30.
Member
Author
|
I checked this PR independently against the final commit 7b2c337 (CPU, CCE,
Developed with Claude Code. |
Member
Author
|
Note on interaction with #1969: in the GREEN run here, near-wall gas still reaches ~2850 K next to the 1800 K isothermal wall. That over-heating comes from the existing hot-wall ghost extrapolation (image-point sample distance), which #1969 fixes; with #1969 the rim ghost states are less extreme, so this face-state guard should trigger less often. The two are complementary: #1969 corrects the ghost values, this PR guards the reconstruction against out-of-range face states that remain at sharp corners. (Developed with Claude Code.) |
…of a first-order revert Replaces s_revert_unphysical_face_states with s_bound_face_states: each cell's reconstructed face states are scaled toward its cell state by one theta shared by both faces, the largest keeping face rho, p and R_mix positive and face T = p/(rho R_mix) <= T_surface_max. All three are linear in theta, so the positivity bound is closed form and the temperature bound the first root of a quadratic: continuous, no iteration. Range and loop style follow the species-bounds limiter. Regenerates 4646053A (tolerance 1e-5: corner faces amplify roundoff) and the burning-grain goldens B317404C and E5B66084, whose blowing ghost cells reconstruct a negative face density (-0.059 vs cell 0.020) that the limiter now scales.
Lines of Code
|
sbryngelson
force-pushed
the
fix-cylinder-rim
branch
from
October 10, 2026 16:27
96dec4f to
f23fb7d
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Contribution Policy
All contributions are expected to demonstrate:
If these expectations are not met, we would prefer to implement the changes ourselves rather than spend time reviewing low-effort submissions.
Fixes #1964
Root cause
This is not a levelset or image-point bug. I checked every ghost point of the repro cylinder offline (same marker, levelset, image-point and stencil logic as master). Every image point lands in fluid, and every interpolation stencil has at least 4 fluid points (
cm3c_cases/debug_E/cyl_rim/tools/geom.py).The failure happens like this:
thermal_bc = 1, Twall = 1800 K), the ghost densities in that column are 0.14, 0.24, 0.27 and 0.28 kg/m^3, next to fluid at 1.05. The column is non-monotone.Instrumented trace from a restart at step 21 of the repro: at stage 3 of step 22, face (12, 17.5, 24) has ρ_R = 0.059 and p_R = 1.31e5, and the y-flux there is NaN. Non-reacting finite rods (no chemistry, adiabatic wall) run cleanly. With chemistry, an adiabatic IB (
thermal_bc = 0) or an ambient-temperature wall (Twall = 350 K) also runs cleanly. The hot isothermal wall is the ingredient that drives this to NaN.A convex corner has no single ghost value that suits both faces. A real fix at the IB level needs a new corner treatment (e.g., per-direction ghost states). This PR bounds the reconstructed face states where the NaN is produced.
#1969 alone does not fix this. #1969 extrapolates the hot-wall ghost from where the image point is actually sampled. On the repro it cools the shallowest rim ghost layer (step 21: 3176 K → 2063 K, ρ 0.137 → 0.193) but leaves layers 2–4 at ~3120 K, so the column is still non-monotone. The NaN is delayed, not removed: the 3D repro NaNs at step 26 instead of 22 (cell (12, 18, 21), the same rim position), and the 2D rectangle case at step 70 instead of 24.
Change
m_rhs.fpp: news_bound_face_states(id), run after reconstruction whenchemistryis on. It is a Zhang–Shu scaling limiter. Each cell's two face states (all primitive variables) are scaled toward the cell state by one θ ∈ [0, 1]. θ is the largest value that keeps face ρ, p and R_mix above 1e-12 of the cell value and face T = p/(ρ R_mix) ≤T_surface_max.T_surface_maxis 5000 K, the thermo windowm_ibmalready uses. ρ, p and R_mix are all linear in θ. So the positivity bound is closed form, and the T bound is the first root of a quadratic. That makes θ continuous in the data, with no iteration. θ = 1 (no change) wherever the faces are already in bounds. There is no lower T bound: an earlier 200 K bound moved1D -> Chemistry -> MultiComponent Diffusion. The range and the GPU loop style follow the species-bounds limiter (Keep species mass fractions in [0, 1] by construction instead of clipping #1963), so it runs over the range the reconstruction filled, with θ shared by both faces of a cell.2D -> Chemistry -> IBM -> Hot Wall Rectangle Corners(4646053A). It uses h2o2.yaml, 72x48 cells, 30 steps, ~3 s on CPU. It is the 2D analog: Mach 1.5 air onto an 1800 K isothermal IB rectangle. On master it aborts at step 30 (ICFL is NaN).Evidence (CPU, CCE, serial
--no-mpi)./mfc.sh test --no-mpi --no-gpu:-o IBM: 62 passed.A69D2D28failed once with a transientNo such file or directory: '0'and passed on rerun.-o Cylinder: 8 passed.-o Chemistry: 23 passed.2D -> IBM -> Vieille Burn Rate) and E5B66084 (2D -> Example -> ibm_burning_grain): the same case. On master, a blowing ghost cell inside the grain reconstructs a negative face density (ρ_face = −0.059 next to a cell ρ = 0.020, so face T < 0). HLLC is fed that state on master. The revert only touched that face, and the change stayed under the 1e-3 test tolerance. The limiter scales both faces of that cell (θ = 0.20). Fluid momentum moves by up to 3.7% relative where |value| > 1e-6, and the IB force (small in magnitude) changes a lot. With a per-face θ instead, I checked that B317404C stays within its tolerance. I kept the shared per-cell θ for consistency with Keep species mass fractions in [0, 1] by construction instead of clipping #1963. Reviewers may prefer per-face θ../mfc.sh precheckpasses.Not verified